package cn.cas.mango.util.singlepass;

import cn.cas.mango.dto.HotListDetail;
import cn.cas.mango.dto.param.HotListDetailParam;
import cn.cas.mango.util.Matrix;
import co.elastic.clients.elasticsearch.core.search.Hit;
import io.swagger.models.auth.In;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

// 聚类算法，singlepass，根据向量一次遍历。
public class SinglePass {
  private List<List<HotListDetail>> lists;
  private double aggWeight;
  private Integer vectorSize;
  public SinglePass(List<List<HotListDetail>> lists, double aggWeight, Integer vectorSize) {
    this.lists = lists;
    this.aggWeight = aggWeight;
    this.vectorSize = vectorSize;
  }

  public  List<List<HotListDetail>> getClusters() {
    List<List<HotListDetail>> ret = new ArrayList<>();
    for (List<HotListDetail> list: lists) {
      List<List<HotListDetail>> cluster = singlePass(list, aggWeight);
      ret.addAll(cluster);
    }
    ret.sort((x,y)->-Integer.valueOf(x.size()).compareTo(y.size()));
    return ret;
  }

  public List<List<HotListDetail>> singlePass(List<HotListDetail> newsList, double threshold) {
    List<List<HotListDetail>> ret = new ArrayList<>();
    for (int i = 0; i < newsList.size(); i++) {
      boolean flag = false;
      HotListDetail now = newsList.get(i);
      for (int j = 0; j < ret.size(); j++) {
        List<HotListDetail> cluster = ret.get(j);
        List<Double> avg = Matrix.getAvg(cluster.stream()
            .map(x -> (List<Double>) x.getVector()).collect(Collectors.toList()),
            vectorSize);
        List<Double> vector = (List<Double>)now.getVector();

        double v = Matrix.cosineSimilarity(avg, vector);
        if (v > threshold) {
          cluster.add(now);
          flag = true;
          break;
        }
      }
      if (!flag) {
        List<HotListDetail> temp = new ArrayList<>();
        temp.add(now);
        ret.add(temp);
      }

    }
    return ret;
  }

}
